/**
 * AS - the open source Automotive Software on https://github.com/parai
 *
 * Copyright (C) 2017 AS <parai@foxmail.com>
 *
 * This source code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * This file should be generated by studio, but I feel terrified to work on the studio/generator
 * as there are so many RTE interface, so hoping some open source RTE generator could cover this
 * and then integrated it. Now the python autosar(https://github.com/cogu/autosar) only generate the
 * upper-layer interface, so hard code to map those interface to BSW low-layer interface.
 */
/* ============================ [ INCLUDES  ] ====================================================== */
#include "Os.h"
#include "Rte_Telltale.h"
#include "Dio.h"
/* ============================ [ MACROS    ] ====================================================== */
#define RTE_WRITE_PORT_FOR_TELLTALE(name)					\
		Std_ReturnType Rte_Write_Telltale_Telltale_##name##State(OnOff_T data)				\
		{																					\
			Std_ReturnType ercd = E_NOT_OK;													\
			if(data < eTelltaleStatusMax)													\
			{																				\
				TelltaleStatus[eTelltale##name] = data;										\
				ercd = E_OK;																\
			}																				\
			return ercd;																	\
		}

#define TELLTALE_MGR_PERIOD 5
#define mMS2Ticks(t) (((t)+TELLTALE_MGR_PERIOD-1)/TELLTALE_MGR_PERIOD)
/* ============================ [ TYPES     ] ====================================================== */
enum {
	eTelltaleTPMS = 0,
	eTelltaleLowOil,
	eTelltalePosLamp,
	eTelltaleTurnLeft,
	eTelltaleTurnRight,
	eTelltaleAutoCruise,
	eTelltaleHighBeam,
	eTelltaleSeatbeltDriver,
	eTelltaleSeatbeltPassenger,
	eTelltaleAirbag,
	eTelltaleMax
};

enum
{
	eTelltaleStatusOff = 0,
	eTelltaleStatusOn,
	eTelltaleStatus1Hz,
	eTelltaleStatus2Hz,
	eTelltaleStatus3Hz,
	eTelltaleStatusMax
};
/* ============================ [ DECLARES  ] ====================================================== */
/* ============================ [ DATAS     ] ====================================================== */
static TimerType     TellatleTimer[eTelltaleStatusMax];
static Dio_LevelType TellatleLevel[eTelltaleStatusMax];
static const Dio_ChannelType TellatleChannel[eTelltaleMax] =
{
	DIO_CHL_TelltaleTPMS,
	DIO_CHL_TelltaleLowOil,
	DIO_CHL_TelltalePosLamp,
	DIO_CHL_TelltaleTurnLeft,
	DIO_CHL_TelltaleTurnRight,
	DIO_CHL_TelltaleAutoCruise,
	DIO_CHL_TelltaleHighBeam,
	DIO_CHL_TelltaleSeatbeltDriver,
	DIO_CHL_TelltaleSeatbeltPassenger,
	DIO_CHL_TelltaleAirbag
};

static const TimerType    TellatleHzCfg[eTelltaleStatusMax][2] =
{ /* { duty, period } */
	{mMS2Ticks(1000), mMS2Ticks(1000)-1}, /* eTelltaleStatusOff */
	{mMS2Ticks(0),    mMS2Ticks(0)   -1}, /* eTelltaleStatusOn */
	{mMS2Ticks(500),  mMS2Ticks(1000)-1}, /* eTelltaleStatus1Hz */
	{mMS2Ticks(250),  mMS2Ticks(500) -1}, /* eTelltaleStatus2Hz */
	{mMS2Ticks(167),  mMS2Ticks(333) -1}, /* eTelltaleStatus3Hz */
};
/* ============================ [ LOCALS    ] ====================================================== */
static OnOff_T TelltaleStatus[eTelltaleMax];
/* ============================ [ FUNCTIONS ] ====================================================== */
RTE_WRITE_PORT_FOR_TELLTALE(TPMS)
RTE_WRITE_PORT_FOR_TELLTALE(LowOil)
RTE_WRITE_PORT_FOR_TELLTALE(PosLamp)
RTE_WRITE_PORT_FOR_TELLTALE(TurnLeft)
RTE_WRITE_PORT_FOR_TELLTALE(TurnRight)
RTE_WRITE_PORT_FOR_TELLTALE(AutoCruise)
RTE_WRITE_PORT_FOR_TELLTALE(HighBeam)
RTE_WRITE_PORT_FOR_TELLTALE(SeatbeltDriver)
RTE_WRITE_PORT_FOR_TELLTALE(SeatbeltPassenger)
RTE_WRITE_PORT_FOR_TELLTALE(Airbag)


void Swc_TelltaleManager(void)
{	/* period is 5ms */
	int i;
	for(i=0;i<eTelltaleStatusMax;i++)
	{
		TellatleTimer[i]++;
		if(TellatleTimer[i] < TellatleHzCfg[i][0])
		{ /* in the low duty */
			TellatleLevel[i] = STD_LOW; /* off the Telltale */
		}
		else
		{
			TellatleLevel[i] = STD_HIGH; /* on the Telltale */
			if(TellatleTimer[i] > TellatleHzCfg[i][1])
			{ /* reach the period */
				TellatleTimer[i] = 0;
				TellatleLevel[i] = STD_LOW; /* off the Telltale */
			}
		}
	}
	/* refresh Telltale */
	for(i=0; i<eTelltaleMax; i++)
	{
		Dio_WriteChannel(TellatleChannel[i],TellatleLevel[TelltaleStatus[i]]);
	}
}

